﻿using CommonViews.Configs;
using CommonViews.Models;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Database.ERPNext;
using Main.Configs;
using Main.Controls;
using Main.Messages;
using Main.Models;
using Main.Tools;
using Main.Views;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Printing;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;

namespace Main.ViewModels
{
    internal partial class VoucherPrintViewModel : ObservableObject
    {
        [ObservableProperty]
        bool isPrinting = false;

        [RelayCommand]
        void ModifyOutputFolder()
        {
            // Configure open folder dialog box
            Microsoft.Win32.OpenFolderDialog dialog = new();

            dialog.Multiselect = false;
            dialog.Title = "请选择一个文件夹";

            // Show open folder dialog box
            bool? result = dialog.ShowDialog();

            // Process open folder dialog box results
            if (result == true)
            {
                // Get the selected folder
                string fullPathToFolder = dialog.FolderName;
                VoucherPrintConfig.Current.OutputFolder = fullPathToFolder;
                VoucherPrintConfig.Current.Save();

            }
        }


        CancellationTokenSource _cts = new CancellationTokenSource();

        [RelayCommand]
        async Task PrintSelected()
        {
            _cts = new CancellationTokenSource();
            IsPrinting = true;
            var onlyNotYetPrint = VoucherPrintConfig.Current.OnlyNotYetPrinted ? "是" : "否";
            Serilog.Log.Information($"【凭证打印】所选凭证(仅未打印={onlyNotYetPrint})");            

            await PrintVouchers(_cts, GloabalViewModel.GLEntry_DataListViewModel.SelectedDataItems,VoucherPrintConfig.Current.OnlyNotYetPrinted);
           
            IsPrinting = false;
        }

        [RelayCommand]
        async Task PrintFiltered()
        {
            _cts = new CancellationTokenSource();
            IsPrinting = true;
            var onlyNotYetPrint = VoucherPrintConfig.Current.OnlyNotYetPrinted ? "是" : "否";
            Serilog.Log.Information($"【凭证打印】筛选后凭证(仅未打印={onlyNotYetPrint})");
            await PrintVouchers(_cts, GloabalViewModel.GLEntry_DataListViewModel.DataItems, VoucherPrintConfig.Current.OnlyNotYetPrinted);
            IsPrinting = false;
        }

        [RelayCommand]
        async Task PrintAll()
        {
            _cts = new CancellationTokenSource();
            IsPrinting = true;
            var onlyNotYetPrint = VoucherPrintConfig.Current.OnlyNotYetPrinted ? "是" : "否";
            Serilog.Log.Information($"【凭证打印】全部凭证(仅未打印={onlyNotYetPrint})");
            await PrintVouchers(_cts, GloabalViewModel.GLEntry_DataListViewModel.SourceQuery, VoucherPrintConfig.Current.OnlyNotYetPrinted);
            IsPrinting = false;
        }

        [RelayCommand]
        void StopPrinting()
        {
            if (MessageBox.Show("您确定要终止操作吗？",
                    "终止操作",
                    MessageBoxButton.YesNo,
                    MessageBoxImage.Question) == MessageBoxResult.Yes)
            {
                Serilog.Log.Information($"【凭证打印】用户请求终止操作");
                _cts.Cancel();
            }            
            
        }

        async Task PrintVouchers(CancellationTokenSource cts, IEnumerable<tabGL_Entry> gL_Entries,bool onlyNotYetPrinted)
        {
            List<VoucherToPrint> vouchers_to_print = null;

            //这里要用Task.Run，用Application.Current.Dispatcher.Invoke界面无反应
            await Task.Run(() =>
            {
                Serilog.Log.Information($"【凭证打印】生成打印数据...");
                vouchers_to_print = VoucherToPrint.MakeVochersToPrint(gL_Entries, cts.Token, onlyNotYetPrinted);
                if (cts.Token.IsCancellationRequested)
                {
                    Serilog.Log.Information($"【凭证打印】用户终止");
                    return;
                }
                Serilog.Log.Information($"【凭证打印】生成打印数据完成");
            });

            //这里不能用Task.Run，会出现异常：调用线程必须为STA，因为许多UI组件都需要
            Application.Current.Dispatcher.Invoke(() => {                

                if (vouchers_to_print != null && vouchers_to_print.Count > 0)
                {
                    //打开最基本的打印对话框
                    PrintDialog printDialog = new PrintDialog();

                    //设置打印机
                    PrintServer server = new PrintServer();
                    //var queues=server.GetPrintQueues();
                    var queu = server.GetPrintQueue(VoucherPrintConfig.Current.PrintQueueName);
                    if (queu != null)
                    {
                        printDialog.PrintQueue = queu;

                        //设置纸张
                        printDialog.PrintTicket.PageMediaType = VoucherPrintConfig.Current.PageMediaType;
                        printDialog.PrintTicket.PageOrientation = VoucherPrintConfig.Current.PageOrientation;
                        printDialog.PrintTicket.PageMediaSize = new PageMediaSize(VoucherPrintConfig.Current.PageMediaSizeName, VoucherPrintConfig.Current.PageWidth, VoucherPrintConfig.Current.PageHeight);
                    }




                    // 设置所有页
                    printDialog.PageRangeSelection = PageRangeSelection.AllPages;

                    // 设置是否启用用户页面范围
                    //printDialog.UserPageRangeEnabled = true;

                    // 设置是否启用当前页面
                    //printDialog.CurrentPageEnabled = true;

                    // 设置是否启用选定页面
                    //printDialog.SelectedPagesEnabled = true;






                    //获取打印区域宽度和高度
                    double printableAreaWidth = printDialog.PrintableAreaWidth;
                    double printableAreaHeight = printDialog.PrintableAreaHeight;

                    // 获取打印队列
                    PrintQueue printQueue = printDialog.PrintQueue;
                    // 获取打印票证
                    PrintTicket printTicket = printDialog.PrintTicket;

                    // 获取页面范围选择
                    PageRangeSelection pageRangeSelection = printDialog.PageRangeSelection;


                    //把所有打印数据加入队列
                    Queue<VoucherPrintPaperViewModel> vm_queue = new Queue<VoucherPrintPaperViewModel>();
                    Serilog.Log.Information($"【凭证打印】生成打印队列...");
                    foreach (var voucher in vouchers_to_print)
                    {
                        if (cts.Token.IsCancellationRequested)
                        {
                            Serilog.Log.Information($"【凭证打印】用户中断打印");
                            break;
                        }
                        var vms = voucher.GetVoucherPrintPaperViewModels();
                        foreach (var vm in vms)
                        {
                            vm_queue.Enqueue(vm);
                        }
                    }
                    Serilog.Log.Information($"【凭证打印】打印队列生成完毕");

                    //注册消息
                    WeakReferenceMessenger.Default.Register<VoucherPrintDlgReadyMessage>(this, (r, m) =>
                    {
                        if (vm_queue.Count > 0)
                        {
                            var vm = vm_queue.Dequeue();
                            Serilog.Log.Information($"【凭证打印】待打印：{vm.VoucherNoDetail}");
                            WeakReferenceMessenger.Default.Send<VoucherInfoMessage>(new VoucherInfoMessage(vm, printDialog));
                        }
                        else
                        {
                            Serilog.Log.Information($"【凭证打印】打印任务完成");
                            //发送完成消息
                            WeakReferenceMessenger.Default.Send<VoucherPrintDoneMessage>(new VoucherPrintDoneMessage());
                        }

                    });



                    //显示对话框
                    PrintingWindow printingWindow = new PrintingWindow();
                    printingWindow.ShowDialog();

                    //取消消息注册
                    WeakReferenceMessenger.Default.Unregister<VoucherPrintDlgReadyMessage>(this);



                }
            });


            
                  
            
        }
    }
}
